package cn.tedu.boyou.search.service.impl;

import cn.tedu.boyou.search.query.SearchQueryObject;
import cn.tedu.boyou.search.repository.IStrategyTemplateRepository;
import cn.tedu.boyou.search.service.IStrategySearchService;
import cn.tedu.boyou.search.template.StrategyTemplate;
import cn.tedu.boyou.search.vo.StatisVO;
import com.alibaba.dubbo.config.annotation.Service;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregation;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
import org.elasticsearch.search.aggregations.bucket.composite.TermsValuesSourceBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;

import java.util.*;

@Service
public class StrategySearchServiceImpl implements IStrategySearchService {

    @Autowired
    private IStrategyTemplateRepository dao;

    @Autowired
    private ElasticsearchTemplate template;

    @Autowired
    private TransportClient client;

    public void createIndex() {
        template.createIndex(StrategyTemplate.class);
        template.putMapping(StrategyTemplate.class);
    }

    public void save(StrategyTemplate t) {
        dao.save(t);
    }

    public List<Map<String, Object>> queryThemeCommends() {
        List<CompositeValuesSourceBuilder<?>> sources =  new ArrayList<>();
        //构建分组字段对象
        TermsValuesSourceBuilder idSource = new TermsValuesSourceBuilder("id");//名字
        idSource.field("themeId");  //分组字段
        idSource.missingBucket(true);//忽略不满足条件的bucket

        TermsValuesSourceBuilder nameSource = new TermsValuesSourceBuilder("name");//名字
        nameSource.field("themeName");  //分组字段
        nameSource.missingBucket(true);//忽略不满足条件的bucket

        sources.add(idSource);
        sources.add(nameSource);

        //参数1：分组名称
        //参数2:分组字段集合
        CompositeAggregationBuilder builder = new CompositeAggregationBuilder("themeGroup",sources);

        //查询请求组对象:设置所有
        SearchRequest request = new SearchRequest(StrategyTemplate.INDEX_NAME);
        //设置类型
        request.types(StrategyTemplate.TYPE_NAME);

        request.source(new SearchSourceBuilder()
                .aggregation(builder)
                .size(0)

        );

        //请求发起
        SearchResponse response = this.client.search(request).actionGet();

        Aggregations aggregations = response.getAggregations();
        //聚合查询分组对象
        CompositeAggregation compositeAggregation = aggregations.get("themeGroup");

        List<? extends CompositeAggregation.Bucket> buckets = compositeAggregation.getBuckets();

        List<StatisVO> themesVos = new ArrayList<>();
        for (CompositeAggregation.Bucket bucket : buckets) {
            StatisVO vo = new StatisVO();

            Map<String, Object> key = bucket.getKey();
            long docCount = bucket.getDocCount();
            vo.setId(Long.valueOf(key.get("id").toString()));
            vo.setName(key.get("name").toString());
            vo.setCount(docCount);

            themesVos.add(vo);
        }

        //排序前10
        Collections.sort(themesVos, new Comparator<StatisVO>() {
            public int compare(StatisVO o1, StatisVO o2) {
                return o2.getCount().compareTo(o1.getCount());
            }
        });

        //截取前10个
        if(themesVos.size() > 10){
            themesVos.subList(0,10);
        }
        //外层的list
        List<Map<String,Object>> data = new ArrayList<>();
        //内层：主题 + 目的地集合
        Map<String,Object> map;

        for (StatisVO vo : themesVos) {
            List<StatisVO> list = queryDestByThemeId(vo.getId());
            map = new HashMap<>();
            map.put("theme",vo);    //主题
            map.put("dests",list);  //目的地
            data.add(map);
        }


        return data;
    }

    public List<StatisVO> queryStrategyCondition(int conditionType) {
        List<CompositeValuesSourceBuilder<?>> sources =  new ArrayList<>();
        //构建分组字段对象
        TermsValuesSourceBuilder idSource = new TermsValuesSourceBuilder("id");//名字
        idSource.missingBucket(true);//忽略不满足条件的bucket

        TermsValuesSourceBuilder nameSource = new TermsValuesSourceBuilder("name");//名字
        nameSource.missingBucket(true);//忽略不满足条件的bucket


        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        if(conditionType == SearchQueryObject.CONDITION_TYPE_ABROAD){
            //countryId
            //countryName
            idSource.field("countryId"); //分组字段
            nameSource.field("countryName");
            //拼接条件：countryId <> 1
            boolQuery.mustNot(QueryBuilders.termQuery("countryId",1));


        }else if(conditionType == SearchQueryObject.CONDITION_TYPE_UN_ABROAD){
            //provinceId
            //provinceName
            idSource.field("provinceId"); //分组字段
            nameSource.field("provinceName");
            //拼接条件：countryId = 1
            boolQuery.must(QueryBuilders.termQuery("countryId",1));

        }else if(conditionType == SearchQueryObject.CONDITION_TYPE_THEME){
            //themeId
            //themeName
            idSource.field("themeId");  //分组字段
            nameSource.field("themeName");  //分组字段
        }


        sources.add(idSource);
        sources.add(nameSource);


        //参数1：分组名称
        //参数2:分组字段集合
        CompositeAggregationBuilder builder = new CompositeAggregationBuilder("conditionGroup",sources);

        //查询请求组对象:设置所有
        SearchRequest request = new SearchRequest(StrategyTemplate.INDEX_NAME);
        //设置类型
        request.types(StrategyTemplate.TYPE_NAME);

        request.source(new SearchSourceBuilder()
                .aggregation(builder)
                .query(boolQuery)
                .size(0)

        );

        //请求发起
        SearchResponse response = this.client.search(request).actionGet();

        Aggregations aggregations = response.getAggregations();
        //聚合查询分组对象
        CompositeAggregation compositeAggregation = aggregations.get("conditionGroup");

        List<? extends CompositeAggregation.Bucket> buckets = compositeAggregation.getBuckets();

        List<StatisVO> Vos = new ArrayList<>();
        for (CompositeAggregation.Bucket bucket : buckets) {
            StatisVO vo = new StatisVO();

            Map<String, Object> key = bucket.getKey();
            long docCount = bucket.getDocCount();
            vo.setId(Long.valueOf(key.get("id").toString()));
            vo.setName(key.get("name").toString());
            vo.setCount(docCount);

            Vos.add(vo);
        }


        //排序前10
        Collections.sort(Vos, new Comparator<StatisVO>() {
            public int compare(StatisVO o1, StatisVO o2) {
                return o2.getCount().compareTo(o1.getCount());
            }
        });

        return Vos;
    }

    public Page<StrategyTemplate> query(SearchQueryObject qo) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        if(qo.getType() == SearchQueryObject.CONDITION_TYPE_ABROAD){
            boolQuery.must(QueryBuilders.termQuery("countryId",qo.getTypeValue()));

        }else if(qo.getType() == SearchQueryObject.CONDITION_TYPE_UN_ABROAD){
            boolQuery.must(QueryBuilders.termQuery("provinceId",qo.getTypeValue()));

        }else if(qo.getType() == SearchQueryObject.CONDITION_TYPE_THEME){
            boolQuery.must(QueryBuilders.termQuery("themeId",qo.getTypeValue()  ));
        }
        Page<StrategyTemplate> page = dao.search(boolQuery, qo.getPageable());
        return page;
    }

    public Page<StrategyTemplate> queryByDestId(SearchQueryObject qo) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if(qo.getDestId() != -1){
            boolQuery.must(QueryBuilders.termQuery("destId", qo.getDestId()));
        }
        return dao.search(boolQuery,qo.getPageableWithoutSort());
    }

    private List<StatisVO> queryDestByThemeId(Long themeId){
        List<StatisVO> list = new ArrayList<>();

        //destId destName
        Iterable<StrategyTemplate> dests = dao.search(QueryBuilders.termQuery("themeId", themeId));

        //名字去重
        List<String> names = new ArrayList<>();
        dests.forEach(s -> {
            if(!names.contains(s.getDestName())){
                StatisVO vo = new StatisVO();
                vo.setId(s.getDestId());
                vo.setName(s.getDestName());
                list.add(vo);
                names.add(s.getDestName());
            }
        });
        return list;
    }

    public List<StatisVO> statisGroup(String idField,String nameField,String groupName,BoolQueryBuilder query) {
        List<CompositeValuesSourceBuilder<?>> sources =  new ArrayList<>();
        //构建分组字段对象
        TermsValuesSourceBuilder idSource = new TermsValuesSourceBuilder("id");//名字
        idSource.field(idField);  //分组字段
        idSource.missingBucket(true);//忽略不满足条件的bucket

        TermsValuesSourceBuilder nameSource = new TermsValuesSourceBuilder("name");//名字
        nameSource.field(nameField);  //分组字段
        nameSource.missingBucket(true);//忽略不满足条件的bucket

        sources.add(idSource);
        sources.add(nameSource);
        if(query == null){
            query = QueryBuilders.boolQuery();
        }

        //参数1：分组名称
        //参数2:分组字段集合
        CompositeAggregationBuilder builder = new CompositeAggregationBuilder(groupName,sources);

        //查询请求组对象:设置所有
        SearchRequest request = new SearchRequest(StrategyTemplate.INDEX_NAME);
        //设置类型
        request.types(StrategyTemplate.TYPE_NAME);

        request.source(new SearchSourceBuilder()
                .aggregation(builder)
                .query(query)
                .size(0)

        );

        //请求发起
        SearchResponse response = this.client.search(request).actionGet();

        Aggregations aggregations = response.getAggregations();
        //聚合查询分组对象
        CompositeAggregation compositeAggregation = aggregations.get(groupName);

        List<? extends CompositeAggregation.Bucket> buckets = compositeAggregation.getBuckets();

        List<StatisVO> vos = new ArrayList<>();
        for (CompositeAggregation.Bucket bucket : buckets) {
            StatisVO vo = new StatisVO();

            Map<String, Object> key = bucket.getKey();
            long docCount = bucket.getDocCount();
            vo.setId(Long.valueOf(key.get("id").toString()));
            vo.setName(key.get("name").toString());
            vo.setCount(docCount);

            vos.add(vo);
        }

        //排序前10
        Collections.sort(vos, new Comparator<StatisVO>() {
            public int compare(StatisVO o1, StatisVO o2) {
                return o2.getCount().compareTo(o1.getCount());
            }
        });



        return vos;
    }

}

